package com.imooc.mall.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/*
*  打印请求和响应的信息 AOP切面实现
* */
@Aspect  //AOP切面的和通知（切面）
@Component
public class WebLogAspect {
    private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    //切入点的位置在开始的时候执行下面的这个函数
    // 可以不用加入public
    @Pointcut("execution(public * com.imooc.mall.controller.*.*(..))")
    public void webLog(){

    }

    //通知  JoinPoint 连接的点
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint){
        //或者在参数列表使用HttpServletRequest 先获取请求的对象
        //收到请求记录请求内容,SpringMVC为了获取request和response持有上下文的Request容器.通过这个静态的方法直接调用获取请求的所有输入的信息
        ServletRequestAttributes attributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();


        logger.info("URL :" + request.getRequestURI().toString());
        logger.info("HTTP_METHOD :"+ request.getMethod());
        logger.info("IP :"+request.getRemoteAddr());
        logger.info("ClASS_METHOD :"+joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
        logger.info("ARGS :"+ Arrays.toString(joinPoint.getArgs()));
//        logger.info("ARGS :"+ Arrays.toString(joinPoint.getClass().getName()));
//        logger.info("CLASS :"+JoinPoint.class);
        logger.info(String.valueOf(joinPoint.getTarget().getClass())); //获取类的名字
        logger.info("目标方法的"+joinPoint.getSignature().getName()); //获取目标方法的名字
    }


    //切入点（Pointcut）AfterReturning 通知目标方法返回的时候调用这个方法
    @AfterReturning(returning = "res" ,pointcut = "webLog()")
    public void doAfterReturning(Object res) throws JsonProcessingException {
        //处理完请求返回内容 对象转换成json对象的使用WritevValueAsString()
        logger.info("Response :" + new  ObjectMapper().writeValueAsString(res));

    }

}